package com.own.business.level.business.core;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * LevelSpringHook
 *
 * @author 陈学礼
 * @version 1.0
 * @date 2021-06-25 11:42:00
 * @since 3.2.1
 */
@Slf4j
@Component
@SuppressWarnings("all")
public class LevelSpringHook implements ApplicationContextAware, ApplicationListener<ApplicationEvent> {

    private static final Map<String, ExpRuleFunction> EXP_RULE_FUNCTION = new LinkedHashMap<>(8);
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        LevelSpringHook.applicationContext = context;
    }

    /**
     * 获取规则信息
     *
     * @param name 规则名称信息
     */
    public ExpRuleFunction getByName(String name) {
        return EXP_RULE_FUNCTION.get(name);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationReadyEvent) {
            applicationContext.getBeansOfType(ExpRuleFunction.class).forEach((key, service) -> {
                // 判断名称是否重复
                loop:
                if (EXP_RULE_FUNCTION.containsKey(service.type())) {
                    // 判断顺序信息（如果已存在的比当前的顺序大，需要被覆盖）
                    if (EXP_RULE_FUNCTION.get(service.type()).order() > service.order()) {
                        log.warn("接口名称重复===>【{}:{}】", service.type(), key);
                        break loop;
                    }
                    return;
                }
                log.debug("经验获取接口===>【{}:{}】完成注册", service.type(), key);
                EXP_RULE_FUNCTION.put(service.type(), service);
            });
        }
    }

}
